<?php


namespace app\bock\type\stack;


use app\bock\type\bock\IBock;
use app\bock\type\INode;
use app\bock\type\NodeBackGround;
use app\bock\type\NodeStack;
use app\bock\type\Panel;
use app\bock\type\Point;

class PanelStack
{
    /**
     * 堆面板区域
     * @var array
     */
    protected $area;


    /**
     * @var Panel
     */
    protected $panel;

    /**
     * 获取面板高高度, 因为面板和堆是一样高所以直接返回面板高度
     * @return int
     */
    public function getHeight()
    {
        return $this->panel->getHeight();
    }

    public function getWidth()
    {
        return$this->panel->getWith();
    }

    public function getNode(Point $point)
    {
        return $this->panel->getPointNode($point);
    }

    /**
     * @param Panel $panel
     */
    public function setPanel($panel)
    {
        $this->panel = $panel;
        $this->init();
    }

    public function init()
    {
        $this->area = $this->panel->getArea();
    }

    public function addPointStack(Point $point, INode $node)
    {
        $this->panel->setPointNode($point, $node);

        // 添加之后当前面板也需要同步
        $this->area = $this->panel->getArea();

        // 清理之后需要和面板同步
        $this->clearStack();

        $this->panel->setArea($this->area);
    }

    protected function stackDown($line)
    {
        for ($i=$line; $i>0; $i--)
        {
            $this->area[$i] = $this->area[$i-1];
        }
    }

    /**
     * 清理已经满的行
     */
    public function clearStack()
    {
        for ($i=0; $i<$this->getHeight(); $i++)
        {
            if($this->lineIsFull($i))
            {
                $this->stackDown($i);
                $i--;
            }
        }
    }

    protected function lineIsFull($line)
    {
        foreach ($this->area[$line] as $item)
        {
            /**
             * @var INode
             */
            if (!$item instanceof NodeStack){
                return false;
            }
        }

        return true;
    }


    public function isStack(Point $point)
    {
        if ($this->area[$point->getRow()][$point->getCol()] instanceof NodeStack)
        {
            return true;
        }

        return false;
    }

    /**
     * @return array
     */
    public function getOneRowNodes()
    {
        return $this->area[0];
    }

    public function addStackFromBock(IBock $bock)
    {
        $bock->toStack($this);
    }
}